package com.seanLab.tool.es;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.seanLab.domain.Image;
import com.seanLab.domain.TagInfo;
import com.seanLab.dto.RecommendImageDto;
import com.seanLab.dto.RecommendTagInfoDto;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tracy on 17/9/5.
 */
@Component
@ConfigurationProperties(prefix = "com.dasLab.es")
public class ESImageSearch {

    //ImageTagDao imageTagDao = new ImageTagDao();
    @Autowired
    private ImageTagDao imageTagDao;

    private int resultNum;

    public ImageTagDao getImageTagDao() {
        return imageTagDao;
    }

    public void setImageTagDao(ImageTagDao imageTagDao) {
        this.imageTagDao = imageTagDao;
    }

    public int getResultNum() {
        return resultNum;
    }

    public void setResultNum(int resultNum) {
        this.resultNum = resultNum;
    }

    public void initConnection() {
        this.imageTagDao.initConnection(imageTagDao.getHost(), imageTagDao.getPort());
    }


    public int insertImage(Image img){
        int rst=imageTagDao.insertImage(img);
        return rst;
    }

    public int insertImageList(List<Image> imageTagList){
        for (int i=0;i<imageTagList.size();i++){
            imageTagDao.insertImage(imageTagList.get(i));
        }
        return 0;
    }

    public int updateImage(Image img){
        deleteImageByImgid(img.getImgID());
        insertImage(img);
        int rst=imageTagDao.update(img);
        return rst;
    }

    /**
     * delete img by img_id
     * @param imgID
     * @return
     */
    public int deleteImageByImgid(String imgID){//TODO
        String rst=imageTagDao.delete(imgID);
//        System.out.println(rst);
        return -1;
    }

    /**
     * search img by keywords
     * @param tagsList List of String
     * @return
     */
    public List<RecommendImageDto> searchByKeywords(List<String> tagsList){
        ArrayList list=new ArrayList<RecommendImageDto>();
        String ret=imageTagDao.searchWithKeys(tagsList,resultNum);
        System.out.println(ret);
        JSONObject retObj = new JSONObject(ret);
        JSONArray array=retObj.getJSONObject("hits").getJSONArray("hits");
        for(int i=0;i<array.length();i++){
            JSONObject tmp=array.getJSONObject(i);
            list.add(UtilJson.json2RecommendImageDto(tmp.getJSONObject("_source")));//TODO
        }
        return list;
    }

    /**
     * 一级aggs，根据ImageTag的field
     * @param tagsList
     * @param resultNum
     * @param name
     * @param field
     * @return
     */
    public ArrayList<ImageTagRet> facetSearch(List<String> tagsList, int resultNum, String name, String field){
        ArrayList list=new ArrayList<ImageTagRet>();
        String ret=imageTagDao.facetSeach(tagsList,resultNum,name,field);
        JSONObject retObj = new JSONObject(ret);

        JSONArray array=retObj.getJSONObject("hits").getJSONArray("hits");
        System.out.println(array.toString());
        for(int i=0;i<array.length();i++){
            JSONObject tmp=array.getJSONObject(i);
            list.add(json2obj(tmp.getJSONObject("_source"),tmp.getDouble("_score")));
        }

        JSONArray agg=retObj.getJSONObject("aggregations").getJSONObject(name).getJSONArray("buckets");
        System.out.println(agg.toString());
        for(int i=0;i<agg.length();i++){//TODO

        }
        return list;
    }

    public ArrayList<ImageTagRet> facetSeachPostFilter(List<String> tagsList, String filter, int resultNum, String field) { //TODO
        String name="agg_by_"+field;
        ArrayList list=new ArrayList<ImageTagRet>();
        String ret=imageTagDao.facetSeachPostFilter(tagsList,filter,resultNum,name,field);
        JSONObject retObj = new JSONObject(ret);
        JSONArray array=retObj.getJSONObject("hits").getJSONArray("hits");
        for(int i=0;i<array.length();i++){
            JSONObject tmp=array.getJSONObject(i);
            list.add(json2obj(tmp.getJSONObject("_source"),tmp.getDouble("_score")));
        }
        JSONArray agg=retObj.getJSONObject("aggregations").getJSONObject(name).getJSONArray("buckets");
        for(int i=0;i<agg.length();i++){//TODO
            JSONObject x=(JSONObject) agg.get(i);
            System.out.println(x.getInt("doc_count"));
            System.out.println(x.getString("key"));
        }
        return list;
    }

    /**
     * nested aggs
     * @param tagsList search key words
     * @param resultNum number of search result
     * @param field  aggs field
     * @return
     */
    public ArrayList<ImageTagRet> nestedFacetSearch(List<String> tagsList, int resultNum, String path, String field){

        ArrayList list=new ArrayList<ImageTagRet>();
        String name1="by_tag_source";String name2="tag_source";String name3="img_num";
        String ret=imageTagDao.nestedFacetSearch(tagsList,resultNum,path,field,name1,name2,name3);
        JSONObject retObj = new JSONObject(ret);
        System.out.println(ret);
        JSONArray array=retObj.getJSONObject("hits").getJSONArray("hits");
//        System.out.println(array.toString());
        for(int i=0;i<array.length();i++){
            JSONObject tmp=array.getJSONObject(i);
            list.add(json2obj(tmp.getJSONObject("_source"),tmp.getDouble("_score")));
        }

        JSONArray agg=retObj.getJSONObject("aggregations").getJSONObject(name1).getJSONObject(name2).getJSONArray("buckets");
        System.out.println(retObj.getJSONObject("aggregations").toString());
        for(int i=0;i<agg.length();i++){//TODO
            JSONObject x=(JSONObject) agg.get(i);
            x.getJSONObject(name3);
            System.out.println(x.getInt("doc_count"));
            System.out.println(x.getString("key"));
        }
        return list;
    }


    public ArrayList<ImageTagRet> nestedFacetSearchWithFilter(List<String> tagsList, String filter, int resultNum, String field){

        ArrayList list=new ArrayList<ImageTagRet>();
        String name1="by_tag_source";String name2="tag_source";String name3="img_num";
//        String path="Tags";
        String ret=imageTagDao.nestedFacetSearchPostFilter(tagsList,filter,resultNum,field,name1,name2,name3);
        JSONObject retObj = new JSONObject(ret);
        JSONArray array=retObj.getJSONObject("hits").getJSONArray("hits");
//        System.out.println(array.toString());
        for(int i=0;i<array.length();i++){
            JSONObject tmp=array.getJSONObject(i);
            list.add(json2obj(tmp.getJSONObject("_source"),tmp.getDouble("_score")));
        }

        JSONArray agg=retObj.getJSONObject("aggregations").getJSONObject(name1).getJSONObject(name2).getJSONArray("buckets");
        System.out.println(retObj.getJSONObject("aggregations").toString());
        for(int i=0;i<agg.length();i++){//TODO
            JSONObject x=(JSONObject) agg.get(i);
            x.getJSONObject(name3);
            System.out.println(x.getInt("doc_count"));
            System.out.println(x.getString("key"));
        }
        return list;
    }

    public ImageTagRet json2obj(JSONObject o,double score){
        ArrayList list=new ArrayList<TagInfo>();
        JSONArray array=o.getJSONArray("Tags");
        for(int i=0;i<array.length();i++){
//            list.add(TagInfo.json2TagInfo(array.getJSONObject(i)));//TODO
        }
        ImageTagRet imageTag=new ImageTagRet();
        imageTag.setImgID(o.getString("img_id"));
        imageTag.setImgCate(o.getInt("img_cate"));
        imageTag.setImgScore(score);
        imageTag.setImgLocalURL(o.getString("imgLocalURL"));
//        imageTag.setImgSource(o.getString("img_source"));
        imageTag.setImgTagsList(list);
        return imageTag;
    }

    public static void main(String[] args) {
        Image image=new Image();
        image.setImgID("testID2");
        //image.setImgCategory(new int[]{6,3});
        image.setImgSource("B");
        image.setImgURL("testurl");
        image.setImgOriginalURL("oriurl");
        image.setImgDescription("testDisc");
        ArrayList<TagInfo> tmpTag = new ArrayList<TagInfo>();
        tmpTag.add(new TagInfo("id","篮球","A", 0.77, 0));
        tmpTag.add(new TagInfo("id2","NBA", "B", 0.66, 0));
        tmpTag.add(new TagInfo("tid3","冠军","D",  0.33, 0));
        image.setImgTagList(tmpTag);

        ESImageSearch esImageSearch=new ESImageSearch();
        esImageSearch.insertImage(image);

        List l=new ArrayList();
        l.add("冠军");l.add("林丹");
        esImageSearch.searchByKeywords(l);

    }
}
